//  相比之下 JOSN.parse(JSON.stringify())  不能拷贝函数 和特殊类型 比如正则 日期   会导致循环引用

// const deepClone = (target) => {
//   if (typeof target === 'object' && target !== null) {
//     const cloneTarget = Array.isArray(target) ? [] : {};
//     for (let prop in target) {
//       if (target.hasOwnProperty(prop)) {
//         cloneTarget[prop] = deepClone(target[prop]);
//       }
//     }
//     return cloneTarget;
//   } else {
//     return target;
//   }
// }


// function deepClone(obj) {
//   let obj1 = toString.call(obj) == "[Object Array]" ? [] : {}

//   for (let key in obj) {
//     if (typeof obj[key] == 'object') {
//       deepClone(obj[key])
//     } else {
//       if (obj.hasOwnProperty(key)) {
//         obj1[key] = obj[key]
//       }
//     }
//   }
//   return obj1
// }

function deepClone(target, map = new Map()) {
  // 基本数据类型直接返回
  if (typeof target !== 'object') {
    return target
  }

  // 引用数据类型特殊处理
  // 判断数组还是对象
  const temp = Array.isArray(target) ? [] : {}

  if (map.get(target)) {
    // 已存在则直接返回
    return map.get(target)
  }
  // 不存在则第一次设置
  map.set(target, temp)

  for (const key in target) {
    // 递归
    temp[key] = deepClone(target[key], map)
  }
  return temp
}

const a = {
  name: 'sunshine_lin',
  age: 23,
  hobbies: { sports: '篮球', tv: '雍正王朝' },
  works: ['2020', '2021']
}
a.key = a // 环引用
const b = deepClone(a)

console.log(b)
// {
//     name: 'sunshine_lin',
//     age: 23,
//     hobbies: { sports: '篮球', tv: '雍正王朝' },
//     works: [ '2020', '2021' ],
//     key: [Circular]
// }
console.log(b === a) // false






